<template>
    <div class="time-line full-height">
      <yz-condition-filter
        v-model="queryParams"
        @resetSearch="resetSearch"
        @onSubmit="onSubmit"
        class="padding-t-20"
      >
        <yz-input
          v-model.trim="queryParams.date"
          class="q-mr-md"
          inputType="date"
          hint="请选择日期"
          :isRange="false"
          title="日期"
        ></yz-input>
        <workshop-search v-model="queryParams" ref="workShopSearch" :is-shift="false" @endDevice="endDevice" :isFirstDevices="isFirstDevices"/>
      </yz-condition-filter>
      <!--      搜索区-->
      <div class="form-inline bottom justify-between items-center"
           style="padding: 20px; padding-top: 0;position: relative;">
        <q-btn class="btn margin-r-10"
                outline
                color="primary"
                :disable="tableData.length === 0"
                @click="exportExcel">
              导出Excel
        </q-btn>
        <div style="display: flex; top:0.44rem;right:.4rem">
          <div v-for="item in btnType"
               :key="item.label"
               class="q-ml-md flex items-center font-14">
            <div :style="{background:item.color}"
                 class="btn-type q-mr-sm"></div>
            <span class="font-14">{{item.label}}</span>
          </div>
        </div>
      </div>
      <!-- 时间线列表 -->
      <div class="time-line-content scrollbar margin-l-20 margin-r-20"  ref="timeLine">
          <q-list class="time-line-content-list">
            <q-item>
              <q-item-section>
                <div class="q-item-header">
                  <div class="q-item-header-title"
                       style="border-right:1px solid #d3d3d3;border-bottom:1px solid #d3d3d3">轮班名称</div>
                  <div class="q-item-header-text items-center"
                       ref="contentBox">
                       <div style="width:100%;height:100%;padding-left:18px; padding-right: 19px" class="flex">
                       <div style="text-align:center; border-right: 0.5px solid #D3D3D3; height:100%;line-height:48px"
                            class="text-ellipsis"
                            v-for="(item, index) in diffClassList"
                            :key="index"
                            :style="setClassWidth(item, index)">
                         {{item.label}}
                        <q-tooltip>
                          {{item.label}}
                        </q-tooltip>
                       </div>
                       </div>
                    <!-- <canvas id="conCanvas"
                            width=""
                            height="48">
                    </canvas> -->
                  </div>
                </div>
              </q-item-section>
            </q-item>
            <q-item>
              <div class="q-item-nav">
                <div class="q-item-nav-title"
                     style="border-right:1px solid #d3d3d3;border-bottom:1px solid #d3d3d3">时间刻度</div>
                <div class="q-item-nav-text">
                  <canvas id="myCanvas"
                          height="30"
                          width=""
                          style="border:1px solid rgba(211,211,211,1); border-radius:6px">
                  </canvas>
                </div>
              </div>
            </q-item>
            <div  class="overflow-auto scrollbar time-line-content-main">
              <q-item v-for="(item, index) in tableData" :key="item.id">
              <div class="progress">
                <div class="progress-title text-ellipsis overflow-hidden"
                     style="border-right:1px solid #d3d3d3;border-bottom:1px solid #d3d3d3">
                  {{item.label}}
                  <q-tooltip>
                    {{item.label}}
                  </q-tooltip>
                </div>
                <div class="progress-text" @click="onPathDetail(item)">
                  <canvas :id="`shifts${index}`"
                          width=""
                          height="46"
                          style="border:1px solid rgba(211,211,211,1);border-radius:6px">
                  </canvas>
                </div>
              </div>
            </q-item>
            </div>
          </q-list>
      </div>
      <q-inner-loading :showing="isTableLoading" style="z-index: 99">
        <q-spinner-gears size="50px" color="primary" />
      </q-inner-loading>
      <yz-pagination v-model="pagination" @onSearch="onSubmit()" style="position: absolute; bottom: 0px"/>
    </div>
</template>

<script>
import {
  getListTimeLine,
  getStartDateTime
} from '../../boot/status/machine'
import moment from 'moment'
import { addListener } from 'resize-detector'
import { getExportTimeLine } from '../../boot/statistics/stop-stat'
import _ from 'lodash'
import { mapGetters } from 'vuex'
export default {
  name: 'time-line',
  components: {},
  data () {
    return {
      queryParams: {
        date: new Date(),
        boxIds: [],
        workshopId: '',
        location: {
          id: null,
          level: null,
          label: '',
          hash: ''
        },
        devices: ['all']
      },
      isFirstDevices: true,
      requestId: null,
      since: null, // 当天班制开始时间
      before: null, // 当天班制结束时间
      diffCount: 1, // 相差的小时
      countArr: [],
      h: 1, // 计算刻度 按轮班休息的基准 1h / 休息的时长
      btnType: [], // 状态显示情况
      // 班次时间
      classList: [
      ],
      countItem: null,
      count: 40,
      isTableLoading: false,
      tableData: [],
      tableDataClone: [],
      datePro: [],
      dateSin: [],
      pagination: {
        pageNum: 1, // 当前页码
        pageSize: 15, // 每页条数
        rowsNumber: 0 // 总条数
      },
      cloneParams: {},
      classParams: {
        boxId: '',
        id: null,
        date: ''
      }
    }
  },
  computed: {
    ...mapGetters([
      'client', 'statusList'
    ]),
    diffClassList () {
      const member = _.cloneDeep(this.classList)
      if (this.classList.length === 1) {
        return this.classList
      } else {
        for (let i = 0; i < this.classList.length - 1; i++) {
          if (this.setDiffHour(this.classList[i].to, this.classList[i + 1].from) !== 0) {
            let index = _.findIndex(member, v => v.name === this.classList[i].name)
            member.splice(index + 1, 0, {
              name: '换班中',
              label: '换班中',
              to: this.classList[i + 1].from,
              from: this.classList[i].to
            })
          }
        }
        return member
      }
    }
  },
  watch: {
  },
  methods: {
    getListInit () {
      this.$refs.workShopSearch.getWorkshops()
    },
    endDevice () {
      this.onSubmit()
      this.isFirstDevices = false
    },
    exportExcel () {
      console.log('时间线导出')
      let data = {
        ...this.queryParams
      }
      this.$q.loading.show()
      const params = [{ name: '' }]
      const res = this.$getUploadPath(params, '')
      this.requestId = res.fileNameNew
      data = { ...this.cloneParams }
      data['requestId'] = res.fileNameNew
      this.onSubscribe()
      return getExportTimeLine(data).then(res => {
        if (res.code !== '1200') {
          this.$showErrTips('导出异常，请稍后重试')
          this.closeUbscribeTopic()
        }
      }).catch(res => {
        console.log(res)
        this.closeUbscribeTopic()
      })
    },
    onSubscribe () {
      if (this.client) {
        this.client.subscribe(
          `${this.CommonConfig.socketConfig.SOCKET_TOPIC.uploadFile.subscribeTopic}${this.requestId}`, this.onMessageArrived, { id: `${this.requestId}` }
        )
      } else {
        setTimeout(() => {
          this.onSubscribe()
        }, 200)
      }
    },
    closeUbscribeTopic () {
      this.client.unsubscribe(`${this.requestId}`)
      this.$q.loading.hide()
    },
    async onMessageArrived (message) {
      let msg = JSON.parse(message.body).data
      if (msg.requestId !== this.requestId) {
        return
      }
      if (msg.code + '' !== '200') {
        this.$showErrTips('导出异常，请稍后重试')
        this.closeUbscribeTopic()
        return
      }
      const xlsDate = moment(this.cloneParams.date).format('YYYY-MM-DD').replace(/-/g, '')
      await this.$saveFileForBlob(msg.data, `${xlsDate}机台报表_时间线列表.xls`)

      this.closeUbscribeTopic()
      this.$message.success('数据请求成功,请保存文件')
    },
    // 重置
    resetSearch () {
      Object.assign(this.queryParams, this.$options.data.call(this).queryParams)
      this.$refs.workShopSearch.initData()
      this.resizeCanvas('myCanvas')
    },
    // 查询
    onSubmit () {
      this.tableData = []
      this.getListTimeLine()
    },
    onPathDetail (val) {
      val.id = val.deviceId
      this.$router.push({
        path: '/main/status-monitor-v3/machine-list/machine-detail',
        query: {
          id: val.id,
          boxId: val.boxId,
          fromList: false,
          date: moment(this.queryParams.date).format('YYYY-MM-DD')
        }
      })
    },
    // 设置一下动态班次宽度
    setItemHeaderW (val, headerWith) {
      // 暂定2班倒
      // const countItem = ((this.$refs.contentBox.clientWidth - this.count) / 12).toFixed()
      const w = this.$refs.contentBox.clientWidth
      val.map((v, i) => {
        const c = document.querySelector(`#item${i}`)
        c.style.borderRight = '0.5px solid #d3d3d3'
        c.style.borderLeft = '0.5px solid #d3d3d3'
        if (i === 0) {
          c.style.width = ((this.countItem * v.w + 18) / w) * 100 + '%'
          c.style.left = 0
          c.style.borderLeft = 0
        } else {
          c.style.width = ((this.countItem * v.w) / w) * 100 + '%'
        }
        // 最后一行不加border
        if (i === val.length) {
          c.style.borderRight = '0px'
        }
      })
    },
    // 时间线Canvas
    initCanvas () {
      if (!this.$refs.contentBox) {
        return
      }
      const countItem = (this.$refs.contentBox.clientWidth / this.diffCount).toFixed(1)
      this.countItem = countItem
      /**
         *
         *时间线 canvas
         */
      let initW = 0 // 初始宽度
      let c = document.getElementById('myCanvas')
      c.width = this.$refs.contentBox.clientWidth - 3
      let ctx = c.getContext('2d')
      for (let i = 0; i < this.dateSin.length; i++) {
        // let diffI = 1
        ctx.beginPath()
        ctx.lineWidth = 1
        ctx.strokeStyle = '#D3D3D3'
        if (i === 0) {
          initW = 17
        } else if (i === this.dateSin.length - 1) {
          initW = c.width - 17
        } else {
          initW = 17 + 2 * countItem * i
        }
        ctx.moveTo(initW, 0)
        ctx.lineTo(initW, 8)
        ctx.font = '10px PingFang SC'
        ctx.fillStyle = '#333333'
        // word 位置
        ctx.fillText(moment(this.dateSin[i]).format('HH:mm'), initW - 15, 22)
        ctx.stroke()
      }
    },
    // 动态计算班次宽度
    setClassWidth (item, index) {
      const params = item
      let cw = ((this.setDiffHour(params.from, params.to)) * this.countItem).toFixed(1)
      const bgcolor = index % 2 === 0 ? '#fff ' : '#D3D3D3'
      if (index === this.diffClassList.length - 1) {
        return `flex : 1 ; background: ${bgcolor}`
      } else {
        return `width: ${cw + 17}px; background: ${bgcolor}`
      }
    },
    // 动态生成进度canvas
    setProCanvas (val, params) {
      const shifts = params.shifts
      let c = document.getElementById(val)
      c.width = this.$refs.contentBox.clientWidth - this.count
      let ctx = c.getContext('2d')
      // 单元各的时间 暂定1h
      const countItem = (this.$refs.contentBox.clientWidth / this.diffCount).toFixed()
      ctx.beginPath()
      // 绘制矩形x,y,w,h
      // 加工时间 先暂时固定一下
      ctx.fillStyle = '#F3F3F3'
      ctx.fillRect(0, 0, c.width, 32)
      // 下半部分的线条
      // 固定下半部分
      ctx.fillStyle = '#F3F3F3'
      ctx.fillRect(0, 32, c.width, 18)
      ctx.stroke()
      shifts.map(v => {
        if (_.isEmpty(v.events)) {
          return v
        } else {
          v.events.map(y => {
            if (y.type === this.Enums.MACHINES_STATUS.CHANGEOVER.value ||
                y.type === this.Enums.MACHINES_STATUS.BREAKDOWN.value ||
                y.type === this.Enums.MACHINES_STATUS.REPAIR.value
            ) {
              y.typeW = 18
              y.typeY = 'b'
              this.setDownTimeCanvas(y, countItem, ctx)
            } else {
              setTimeout(() => {
                y.typeY = 't'
                y.typeW = 32
                this.setDownTimeCanvas(y, countItem, ctx)
              })
            }
            if (y.type === 4) {
              setTimeout(() => {
                this.setDownTimeCanvas(y, countItem, ctx)
              }, 100)
            }
          })
        }
      })
    },
    // 停机,断开,离线,报警canvas绘制
    // 计算起始位置坐标, ,返回坐标
    setDownTimeCanvas (val, countItem, ctx) {
      const item = _.find(this.btnType, v => v.value === val.type)
      // 与初始时间相差多少小时
      const h = Number((this.setDiffHour(this.since, val.from) * countItem).toFixed(2))
      // 持续多少小时
      const w = Number((this.setDiffHour(val.from, val.to) * countItem).toFixed(2))
      if (val.type !== 4) {
        if (val.typeY === 't') {
          ctx.beginPath()
          ctx.fillStyle = item.color
          ctx.fillRect(h, 0, w, val.typeW)
          ctx.stroke()
        } else if (val.typeY === 'b') {
          ctx.beginPath()
          ctx.fillStyle = item.color
          ctx.fillRect(h, 32, w, val.typeW)
          ctx.stroke()
        }
      } else {
        ctx.beginPath()
        ctx.fillStyle = item.color
        ctx.fillRect(h, 4, w, 24)
        ctx.stroke()
      }
    },
    // 清空canvas
    resizeCanvas (canvas) {
      const c = document.getElementById(canvas)
      if (!c) {
        return
      }
      const ctx = c.getContext('2d')
      ctx.clearRect(0, 0, c.width, c.height)
      this.initCanvas()
      this.tableData.map((v, i) => {
        const item = document.getElementById(`shifts${i}`)
        const itemCtx = item.getContext('2d')
        itemCtx.clearRect(0, 0, item.width, item.height)
        const self = this
        this.$nextTick(() => {
          self.setProCanvas(`shifts${i}`, v)
        })
      })
    },
    initParams () {
      const z = this.$refs.workShopSearch.deviceOptions
      this.classParams = {
        id: !_.isEmpty(z) ? z[0].value : null,
        date: moment(this.queryParams.date).format('YYYY-MM-DD')
      }
      if (!_.isEmpty(z)) {
        this.getStartDateTime(this.classParams)
      }
      return true
    },
    getListTimeLine () {
      // this.classList = []
      // this.datePro = []
      this.isTableLoading = true
      if (!this.initParams()) {
        return
      }
      const params = {
        ...this.queryParams,
        ...this.pagination
      }
      params.date = moment(this.queryParams.date).format('YYYY-MM-DD')
      const { location } = this.queryParams
      params.deviceTreeReqVO = {
        deviceIds: this.queryParams.devices[0] !== 'all' ? this.queryParams.devices : [],
        level: location.level || null,
        schemeId: location.id || null
      }
      this.cloneParams = _.cloneDeep(params)
      getListTimeLine(params)
        .then(res => {
          this.isTableLoading = false
          this.datePro = []
          this.classList = []
          if (res.data.list.length > 0) {
            const ret = _.cloneDeep(res.data.list[0].shifts)
            ret.map((v, i) => {
              const item = v
              item.w = this.setDiffHour(v.from, v.to)
              item.msg = this.setHourArr(v.from, v.to).join('~')
              item.label = v.name + `(${item.msg})`
              this.datePro.push(v.from)
              this.datePro.push(v.to)
              // 班次信息
              this.classList.push(item)
              //
            })
          }
          // 多个设备.
          const params = _.cloneDeep(res.data.list)
          params.map(v => {
            const item = v
            item.label = `${v.deviceName}(${v.assetNumber})`
          })
          this.tableData = _.cloneDeep(params)
          this.pagination.rowsNumber = res.data.total
        }).catch(err => {
          console.log(err)
          this.isTableLoading = false
        })
    },
    // 获取当天班制开始结束时间
    getStartDateTime ({ boxId, id, date }) {
      return getStartDateTime(boxId, id, date).then(res => {
        if (res.data && res.data.since && res.data.before) {
          // this.dateSin = [res.data.since, res.data.before]
          this.diffCount = this.setDiffHour(res.data.since, res.data.before) / this.h
          this.setAllDateHour(res.data.since, res.data.before)
          this.$nextTick(() => {
            this.initCanvas()
          })
          this.since = res.data.since
          this.before = res.data.before
        }
      })
    },
    setAllDateHour (since, before) {
      this.dateSin = []
      const diffH = Math.floor(this.diffCount / 2)
      for (let i = 0; i < diffH; i++) {
        this.dateSin.push(moment(since).add(i * 2, 'hours').format())
        if (i === diffH - 1) {
          this.dateSin.push(before)
        }
      }
    },
    // diff hour
    setDiffHour (since, before) {
      const s = moment(since)
      const b = moment(before)
      const diffHour = b.diff(s, 'seconds')
      return (diffHour / 60 / 60)
    },
    // hour arr[]
    setHourArr (since, before) {
      const s = moment(since).format('HH:mm')
      const b = moment(before).format('HH:mm')
      return [s, b]
    },
    initBtn () {
      const newArr = this.$getEnum(this.Enums.MACHINES_STATUS)
      this.btnType = _.union(_.cloneDeep(this.statusList), newArr.slice(5, newArr.length))
    }
  },
  mounted () {
    this.initBtn()
    this.getListInit()
    addListener(this.$refs.timeLine, this.$utils.debounce(() => {
      this.resizeCanvas('myCanvas')
    }, 100))
    // window.addEventListener('resize', () => {
    //   this.resizeCanvas('myCanvas')
    // })
  }
}
</script>

<style lang="scss" scoped>
  .time-line {
    .btn-type {
      width: 10px;
      height: 10px;
      border-radius: 50%;
    }
    .time-line-content {
      min-width: 660px;
      overflow: auto;
      max-height: calc(100% - 192px);
      border: 1px solid rgba(211, 211, 211, 1);
      border-radius: 6px;
      z-index:99999;
      .q-item-header {
        width: 100%;
        display: flex;
        .q-item-header-title {
          width: 170px;
          text-align: center;
          height: 48px;
          line-height: 48px;
          background: rgba(243, 243, 243, 1);
          font-size: 16px;
          font-family: PingFang SC;
          font-weight: 500;
          color: rgba(51, 51, 51, 1);
        }
        .q-item-header-text {
          width: calc(100% - 170px);
          line-height: 100%;
          position: relative;
          display: flex;
        }
      }
      .q-item-nav {
        display: flex;
        .q-item-nav-title {
          width: 170px;
          text-align: center;
          height: 32px;
          line-height: 32px;
          background: rgba(243, 243, 243, 1);
          font-size: 16px;
          font-family: PingFang SC;
          font-weight: 500;
          color: rgba(51, 51, 51, 1);
        }
        .q-item-nav-text {
          width: calc(100% - 173px);
          height: 32px;
          #myCanvas {
            background: rgba(255, 255, 255, 1);
            box-shadow: inset 0px 0px 10px 0px rgba(0, 0, 0, 0.25);
          }
        }
      }
      .progress{
        width: 100%;
        display: flex;
        .progress-title{
          width: 170px;
          text-align: center;
          height: 56px;
          line-height: 56px;
          background: rgba(243, 243, 243, 1);
          font-size: 16px;
          font-family: PingFang SC;
          font-weight: 500;
          color: rgba(51, 51, 51, 1);
        }
        .progress-text{
          height: 56px;
          width: calc(100% - 173px);
          padding: 4px 16px;
          cursor: pointer;
        }
      }
    }
  }
  .padding-l-20 {
    padding-left: 20px;
  }
</style>
<style lang="scss">
  .time-line {
    .q-item {
      padding: 0px;
      min-height: 24px;
    }
  }
</style>
